package com.torry.replay.infras.tool;

import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;


/**
 * @author torry.wang
 */
public class CodeGenerator implements Serializable {

    static Properties properties;

    static {
        properties = new Properties();
        InputStream in = CodeGenerator.class.getClassLoader().getResourceAsStream("generator.properties");
        try {
            properties.load(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        executeGenerator();
    }

   public static void executeGenerator() {
        AutoGenerator mpg = new AutoGenerator();
        //全局配置
        mpg.setGlobalConfig(buildGlobalConfig());
        // 数据源
        mpg.setDataSource(buildDsc());
        // 包配置
        mpg.setPackageInfo(buildPkCfg());
        // 自定义配置
        mpg.setCfg(buildCfg());
        // 配置模板
        mpg.setTemplate(buildTemplate());
        // 策略配置
        mpg.setStrategy(buildStrategyConfig());
        mpg.execute();
    }

    private static StrategyConfig buildStrategyConfig() {
        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        // 公共父类Controller
        //strategy.setSuperControllerClass("com.torry.recruit.generator.common.base.controller.BaseController");

        // 公共实体类父类
        strategy.setSuperEntityClass("com.zen.boot.starter.mybatisplus.base.Entity");
        // 写于父类中的公共字段
        strategy.setSuperEntityColumns("id", "create_time", "update_time", "deleted", "ext_info");

        strategy.setInclude(properties.getProperty("tables").split(","));
        strategy.setControllerMappingHyphenStyle(true);
        // 表前缀，生成时去除前缀
        strategy.setTablePrefix(properties.getProperty("table_prefix"));
        return strategy;

    }


    private static GlobalConfig buildGlobalConfig() {
        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        String serviceName = properties.getProperty("module-name");
        gc.setOutputDir(projectPath + "/" + serviceName + "/src/main/java");
        gc.setAuthor(properties.getProperty("author"));
        gc.setOpen(false);
        //实体属性 Swagger2 注解
        gc.setSwagger2(true);

        //改生成的类名后缀
        //gc.setServiceName("%sAccessor");
        gc.setEntityName("%sDO");
        gc.setServiceName("%sRepository");
        gc.setServiceImplName("%sRepositoryImpl");
        //gc.setMapperName("%sMapper");
        return gc;
    }


    private static DataSourceConfig buildDsc() {
        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl(properties.getProperty("url"));
        dsc.setDriverName(properties.getProperty("driver"));
        dsc.setUsername(properties.getProperty("username"));
        dsc.setPassword(properties.getProperty("password"));
        return dsc;
    }

    private static PackageConfig buildPkCfg() {
        String serviceName = properties.getProperty("module-name");
        PackageConfig pc = new PackageConfig();
        pc.setModuleName(serviceName.replaceAll("-", ""));
        String basePackage = properties.getProperty("base-package");
        pc.setParent(basePackage);
        pc.setModuleName("");
        // 生成实体类所在的包名
        pc.setEntity(properties.getProperty("entity-package"));
        pc.setMapper(properties.getProperty("mapper-package"));
        pc.setService(properties.getProperty("service-package"));
        pc.setServiceImpl(properties.getProperty("service.impl-package"));
        pc.setController(properties.getProperty("controller-package"));

        return pc;
    }

    private static InjectionConfig buildCfg() {

        String projectPath = System.getProperty("user.dir");
        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
            }
        };

        String templatePath = "/templates/mapper.xml.vm";
        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();
        String moduleName = properties.getProperty("module-name");
        // 自定义配置会被优先输出

        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
                return projectPath + "/" + moduleName + "/src/main/resources/mapper/" + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        cfg.setFileOutConfigList(focList);
        return cfg;
    }

    private static TemplateConfig buildTemplate() {
        TemplateConfig templateConfig = new TemplateConfig();
        String generateOptions = properties.getProperty("generate-options");
        templateConfig.setXml(null);
        if (!generateOptions.contains("controller")) {
            templateConfig.setController("");
        }
        if (!generateOptions.contains("mapper")) {
            templateConfig.setMapper("");
            templateConfig.setXml("");
        }
        if (!generateOptions.contains("service")) {
            templateConfig.setService("");
            templateConfig.setServiceImpl("");
        }
        if (!generateOptions.contains("entity")) {
            templateConfig.setEntity("");
        }
        return templateConfig;
    }

}
